package com.example.bootredis;


import io.netty.util.internal.ObjectUtil;
import org.lionsoul.ip2region.DataBlock;
import org.lionsoul.ip2region.DbConfig;
import org.lionsoul.ip2region.DbSearcher;
import org.lionsoul.ip2region.Util;
import org.springframework.util.ObjectUtils;

import java.io.File;
import java.lang.reflect.Method;
import java.util.LinkedHashSet;
import java.util.Set;

/**
 * @CLassName IpUtils
 * @Author Solming
 * @Date 2019/12/17
 **/
public class IpUtils {


    /*验证IP是否属于某个IP段

     *

     * ipSection    IP段（以'-'分隔）

     * ip           所验证的IP号码

     *

     */

    public static boolean ipExistsInRange(String ip,String ipSection) {

        ipSection = ipSection.trim();

        ip = ip.trim();

        int idx = ipSection.indexOf('-');

        String beginIP = ipSection.substring(0, idx);

        String endIP = ipSection.substring(idx + 1);

        return getIp2long(beginIP)<=getIp2long(ip) &&getIp2long(ip)<=getIp2long(endIP);

    }
    /**
    * @Author Solming
    * @Description: startIp和 enIP 均为转换后如168478580
    * @Date 2019/12/18 
    * @Param [ip, startIp, endIp]
    * @return boolean
    **/
    public static boolean ipExistsInRange(String ip,String startIp,String endIp) {

        startIp = startIp.trim();
        endIp = endIp.trim();
        ip = ip.trim();
        return Long.valueOf(startIp)<=getIp2long(ip) &&getIp2long(ip)<=Long.valueOf(endIp);

    }

    public static long getIp2long(String ip) {

        ip = ip.trim();

        String[] ips = ip.split("\\.");

        long ip2long = 0L;

        for (int i = 0; i < 4; ++i) {

            ip2long = ip2long << 8 | Integer.parseInt(ips[i]);

        }

        return ip2long;

    }

    public static long getIp2long2(String ip) {

        ip = ip.trim();

        String[] ips = ip.split("\\.");

        long ip1 = Integer.parseInt(ips[0]);

        long ip2 = Integer.parseInt(ips[1]);

        long ip3 = Integer.parseInt(ips[2]);

        long ip4 = Integer.parseInt(ips[3]);



        long ip2long =1L* ip1 * 256 * 256 * 256 + ip2 * 256 * 256 + ip3 * 256 + ip4;

        return ip2long;

    }



        public static String getCityInfo(String ip){
            //db
            String dbPath = IpUtils.class.getResource("/ip2region.db").getPath();
            File file = new File(dbPath);
            if ( file.exists() == false ) {
                System.out.println("Error: Invalid ip2region.db file");
            }
            //查询算法
            int algorithm = DbSearcher.BTREE_ALGORITHM; //B-tree
            //DbSearcher.BINARY_ALGORITHM //Binary
            //DbSearcher.MEMORY_ALGORITYM //Memory
            try {
                DbConfig config = new DbConfig();
                DbSearcher searcher = new DbSearcher(config, dbPath);
                //define the method
                Method method = null;
                switch ( algorithm )
                {
                    case DbSearcher.BTREE_ALGORITHM:
                        method = searcher.getClass().getMethod("btreeSearch", String.class);
                        break;
                    case DbSearcher.BINARY_ALGORITHM:
                        method = searcher.getClass().getMethod("binarySearch", String.class);
                        break;
                    case DbSearcher.MEMORY_ALGORITYM:
                        method = searcher.getClass().getMethod("memorySearch", String.class);
                        break;
                }
                DataBlock dataBlock = null;
                if (Util.isIpAddress(ip) == false ) {
                    System.out.println("Error: Invalid ip address");
                }
                dataBlock  = (DataBlock) method.invoke(searcher, ip);
                if (!ObjectUtils.isEmpty(dataBlock)){
                    String[] addressList =  dataBlock.getRegion().replace("0","").split("\\|");
                    Set<String>  addressSet  = new LinkedHashSet<>();
                    for (String address:addressList){
                        addressSet.add(address);
                    }
                    return String.join("",addressSet);
                }

                return dataBlock.getRegion();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }


    public static void main(String[] args){

        //10.10.10.116 是否属于固定格式的IP段10.10.1.00-10.10.255.255

        String addr = getCityInfo("110.86.13.198");
        System.out.println(addr);
//        String ip="10.10.199.116";
//
//        String ipSection="10.10.1.00-10.10.255.255";
//
//        boolean exists=ipExistsInRange(ip,ipSection);
//
//        System.out.println(exists);
//
//        System.out.println(getIp2long(ip));
//
//        System.out.println(getIp2long2(ip));

    }


}
